Jak nejlepe udelat timeout urcite operace v threadu
Otázka od: Tomas Bradle
24. 8. 2004 23:50
Zdravim vsechny,
mam aplikaci, ktera zabezpecuje uzivatelsky interface k rizeni
technologickych operaci. Jadro rizeni je v samostatnem threadu, pres
synchronize se volaji odezvy do jiz zmineneho uzivatelskeho interface
(hlavni thread aplikace).
Ted bych potrebaval poradit, jak nejlepe udelat testovani timeoutu urcitych
bloku ridiciho kodu, napr.:
zacatek_timeoutu;
repeat
...
until podminka or je_timeout
nebo jinak:
zacatek_timeoutu;
repeat
...
if je_timeout then break;
...
until podminka;
jde mi o to, jak nejlepe udelat mereni ubehnuteho casu, myslel jsem treba
pomoci GetTickCount, ale 47 dni se mi zda malo, kdyz jde o nepretrzity
provoz. Mate nekdo neco vyzouseneho ?
diky
Tomas Bradle
t.bradle@worldonline.cz
Odpovedá: Petr Fejfar
25. 8. 2004 8:12
Tomas Bradle wrote:
> treba pomoci GetTickCount, ale 47 dni se mi zda malo, kdyz jde o
> nepretrzity provoz.
Tak udelej to, co se pri odcitani bezne dela: vypujc si dalsi rad tj. 2^32.
A nebo to muzes nahradit:
- Now a TDateTime
- QueryPerformanceCounter (taky muze pretect)
Co pouzit zalezi na tom, jake mas na TO pozadavky.
HTH, pf
Odpovedá: delphin@post.cz
25. 8. 2004 10:03
> jde mi o to, jak nejlepe udelat mereni ubehnuteho casu, myslel jsem treba
> pomoci GetTickCount, ale 47 dni se mi zda malo, kdyz jde o nepretrzity
> provoz. Mate nekdo neco vyzouseneho ?
Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
var TimeStamp:cardinal;
TimeStamp:=GetTickCount;
repeat
...
if (GetTickCount-TimeStamp)>5000 then break;
...
until podminka;
Now nelze pouzit, protoze cas jednak meni uzivatele, pak automaticka
synchronizace ve WinXP a take zmena letniho a zimniho casu.
Odpovedá: Petr Fejfar
25. 8. 2004 10:22
delphin@post.cz wrote:
> Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
>
> var TimeStamp:cardinal;
>
> TimeStamp:=GetTickCount;
> repeat
> ...
> if (GetTickCount-TimeStamp)>5000 then break;
> ...
> until podminka;
Kdyz dojde k preteceni v ramci mereni periody tj. kdyz nastavis TimeStamp
pred pretecenim a vypocet GetTickCount-Timestamp vyhodnotis
po preteceni, tak to nefunguje. Musis udelat zaporny prenos.
pf
Odpovedá: Tomas Bradle
25. 8. 2004 11:07
Jo tohle presne jsem mel na mysli, takze vlastne staci zjistit jestli novy
TickCount je mensi nez ten, od ktereho se pocita a potom staci provest
korekci napr.:
korig_tc:=int64(GetTickCount)+high(DWORD)+1;
nebo se mylim ?
diky za pomoc
Tomas Bradle
t.bradle@worldonline.cz
----- Original Message -----
From: "Petr Fejfar" <development@callnet.cz>
To: <delphi-l@clexpert.cz>
Sent: Wednesday, August 25, 2004 11:22 AM
Subject: Re: Jak nejlepe udelat timeout urcite operace v threadu
> delphin@post.cz wrote:
>
> > Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
> >
> > var TimeStamp:cardinal;
> >
> > TimeStamp:=GetTickCount;
> > repeat
> > ...
> > if (GetTickCount-TimeStamp)>5000 then break;
> > ...
> > until podminka;
>
> Kdyz dojde k preteceni v ramci mereni periody tj. kdyz nastavis TimeStamp
> pred pretecenim a vypocet GetTickCount-Timestamp vyhodnotis
> po preteceni, tak to nefunguje. Musis udelat zaporny prenos.
>
> pf
>
>
>
>
>
Odpovedá: delphin@post.cz
25. 8. 2004 11:10
> > Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
> >
> > var TimeStamp:cardinal;
> >
> > TimeStamp:=GetTickCount;
> > repeat
> > ...
> > if (GetTickCount-TimeStamp)>5000 then break;
> > ...
> > until podminka;
>
> Kdyz dojde k preteceni v ramci mereni periody tj. kdyz nastavis TimeStamp
> pred pretecenim a vypocet GetTickCount-Timestamp vyhodnotis
> po preteceni, tak to nefunguje. Musis udelat zaporny prenos.
Jak presne to nefunguje ?
O tom, jestli to funguje nebo nefunguje se muzeme snadno presvedcit:
var TimeStamp,TickCount,Result:cardinal;
begin
TimeStamp:=$FFFFFFFF;
TickCount:=$00000000;
Result:=TickCount-TimeStamp;
TickCount TimeStamp Result
$00000000-$FFFFFFFF=$00000001
$00000001-$FFFFFFFF=$00000002
$00000001-$FFFFFFFE=$00000003
$00000002-$FFFFFFFE=$00000004
$00000002-$FFFFFFFD=$00000005
atd ...
Odpovedá: Petr Fejfar
25. 8. 2004 12:54
delphin@post.cz wrote:
> Jak presne to nefunguje ?
> O tom, jestli to funguje nebo nefunguje se muzeme snadno presvedcit:
Clovece mas pravdu - ono to vskutku funguje - Delphi u typu DWORD/CARDINAL
z nejakeho duvodu netestuje preteceni, takze nedojde k Range Check Error,
zatimco u typu WORD a BYTE ano. To jsou veci....
pf
Odpovedá: delphin@post.cz
25. 8. 2004 13:03
> Clovece mas pravdu - ono to vskutku funguje - Delphi u typu DWORD/CARDINAL
> z nejakeho duvodu netestuje preteceni, takze nedojde k Range Check Error,
> zatimco u typu WORD a BYTE ano. To jsou veci....
To se da zapnout/vypnout {$Q+-}a {$R+-}
Odpovedá: Petr Fejfar
25. 8. 2004 14:43
delphin@post.cz wrote:
>> Clovece mas pravdu - ono to vskutku funguje - Delphi u typu
>> DWORD/CARDINAL z nejakeho duvodu netestuje preteceni, takze nedojde
>> k Range Check Error, zatimco u typu WORD a BYTE ano. To jsou veci....
>
> To se da zapnout/vypnout {$Q+-}a {$R+-}
Asi jak komu a jak kdy
- alespon me D6.02prof bere u direktivy $Q posledni hodnotu
v unit, prestoze je v helpu popisovana se scope local,
takze tu direktivu nepouzivame. napr.
...
{$Q-}
Vypocet A; // Vyvola EIntOverflow !!!
{$Q+}
Vypocet B;
a naopak
{$Q+}
Vypocet A; // Nevyvola EIntOverflow !!!
{$Q-}
***
A zapnuti $R+ rozsah u dword nekontroluje vubec (k memu prekvapeni)
- zrejme si rekli, ze co je v registru EAX, to se taky vejde do pameti
a v zasade maji pravdu
pf